package cn.yh.register.order.service.impl;

import cn.yh.register.common.exception.RegisterException;
import cn.yh.register.common.result.ResultCodeEnum;
import cn.yh.register.enums.PaymentTypeEnum;
import cn.yh.register.enums.RefundStatusEnum;
import cn.yh.register.model.order.OrderInfo;
import cn.yh.register.model.order.PaymentInfo;
import cn.yh.register.model.order.RefundInfo;
import cn.yh.register.order.service.OrderService;
import cn.yh.register.order.service.PaymentService;
import cn.yh.register.order.service.RefundInfoService;
import cn.yh.register.order.service.WeiXinService;
import cn.yh.register.order.util.ConstantPropertiesUtils;
import cn.yh.register.order.util.HttpClient;
import com.alibaba.fastjson.JSONObject;
import com.github.wxpay.sdk.WXPayUtil;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * 对接微信支付接口
 * @author dell
 */
@Service
public class WeiXinServiceImpl implements WeiXinService {

    @Autowired
    private OrderService orderService;

    @Autowired
    private PaymentService paymentService;
    @Autowired
    private RefundInfoService refundInfoService;
    /**
     * 对接微信支付接口
     * @param orderId 订单id
     * @return 微信支付返回数据
     */
    @Override
    public Map<String, Object> createNative(Long orderId) throws Exception {
        //1.保存订单信息
        //1.1查询出订单信息
        OrderInfo orderInfo = orderService.getById(orderId);
        //1.3保存交易记录
        paymentService.savePaymentInfo(orderInfo, PaymentTypeEnum.WEIXIN.getStatus());
        //2.组装数据
        Map<String,String> paramMap = new HashMap<>();
        paramMap.put("appid", ConstantPropertiesUtils.APPID);
        paramMap.put("mch_id",ConstantPropertiesUtils.PARTNER);
        paramMap.put("nonce_str", WXPayUtil.generateNonceStr());
        String body = new DateTime(orderInfo.getReserveDate()).toString("yyyy年MM月dd日") + "就诊"+ orderInfo.getDepname();
        paramMap.put("body",body);
        //商户订单号
        paramMap.put("out_trade_no",orderInfo.getOutTradeNo());
        //交易金额
        paramMap.put("total_fee", "1");
        //获取ip
        paramMap.put("spbill_create_ip", "127.0.0.1");
        //通知地址
        paramMap.put("notify_url","https://2495161sb6.goho.co/api/order/weixinPay/weixinNotify");
        //交易类型
        paramMap.put("trade_type","NATIVE");
        //设置交易失效时间
        paramMap.put("time_expire",new DateTime().plusSeconds(30).toString("yyyyMMddHHmmss"));
        //3.请求微信支付接口
        HttpClient client = new HttpClient("https://api.mch.weixin.qq.com/pay/unifiedorder");
        client.setHttps(true);
        //3.1把map数据转成xml
        String xmlContent = WXPayUtil.generateSignedXml(paramMap, ConstantPropertiesUtils.PARTNERKEY);
        client.setXmlParam(xmlContent);
        client.post();
        //4.接收返回数据
        String xml = client.getContent();
        //4.1接收的是xml  转成map
        Map<String, String> resultMap = WXPayUtil.xmlToMap(xml);
        //判断是否成功
        Map<String,Object> map = new HashMap<>();
        if (resultMap.get("return_code").equals("SUCCESS") && resultMap.get("result_code").equals("SUCCESS")){
            //5.成功 处理结果
            map.put("orderId", orderId);
            map.put("totalFee", orderInfo.getAmount());
            map.put("resultCode", resultMap.get("result_code"));
            map.put("codeUrl", resultMap.get("code_url"));
           return map;
        }else{
            throw new RegisterException(resultMap.get("return_msg") + " " + resultMap.get("err_code_des"),
                    ResultCodeEnum.FAIL.getCode());
        }
    }

    /**
     * 微信第三方查看订单状态
     *
     * @param orderId     订单id
     * @param paymentType 支付类型
     * @return 微信第三方返回的数据
     */
    @Override
    public Map<String, String> queryPayStatus(Long orderId, String paymentType) throws Exception {
        //1.查询订单
        OrderInfo orderInfo = orderService.getById(orderId);
        //2.组装数据
        Map<String,String> paramMap = new HashMap<>();
        paramMap.put("appid", ConstantPropertiesUtils.APPID); // 公众号appId
        paramMap.put("mch_id", ConstantPropertiesUtils.PARTNER); // 商户号
        paramMap.put("out_trade_no", orderInfo.getOutTradeNo()); // 商户订单号
        paramMap.put("nonce_str", WXPayUtil.generateNonceStr()); // 随机字符串
        //3.向第三方发送请求
        HttpClient client = new HttpClient("https://api.mch.weixin.qq.com/pay/orderquery");
        //3.1 map转xml
        client.setHttps(true);
        client.setXmlParam(WXPayUtil.generateSignedXml(paramMap, ConstantPropertiesUtils.PARTNERKEY));
//        WXPayUtil.generateSignedXml(paramMap,ConstantPropertiesUtils.PARTNERKEY);
        client.post();
        //4.处理返回的数据
        String xmlContent = client.getContent();
        //4.1 xml转map
        return WXPayUtil.xmlToMap(xmlContent);
    }

    /**
     * 对接微信退款接口
     *
     * @param orderId 订单id
     * @return 是否成功
     */
    @Override
    public Boolean refund(Long orderId) throws Exception {
        //查是否有支付记录
        OrderInfo orderInfo = orderService.getById(orderId);
        if (orderInfo == null){
            throw new RegisterException(ResultCodeEnum.PARAM_ERROR);
        }
        PaymentInfo paymentInfo = paymentService.paymentInfo(orderInfo.getOutTradeNo(), PaymentTypeEnum.WEIXIN.getStatus());
        if (paymentInfo == null){
            throw new RegisterException(ResultCodeEnum.PARAM_ERROR);
        }
        //1.保存退款记录
        RefundInfo refundInfo = refundInfoService.saveRefundInfo(paymentInfo);
        if (Objects.equals(refundInfo.getRefundStatus(), RefundStatusEnum.REFUND.getStatus())) {
            return true;
        }
        //2.组装参数
        Map<String,String> paramMap = new HashMap<>();
        paramMap.put("appid",ConstantPropertiesUtils.APPID);       // 公众账号ID
        paramMap.put("mch_id",ConstantPropertiesUtils.PARTNER);   // 商户号
        paramMap.put("nonce_str",WXPayUtil.generateNonceStr()); // 随机字符串
        paramMap.put("transaction_id",paymentInfo.getTradeNo()); // 微信交易流水号
        paramMap.put("out_trade_no",paymentInfo.getOutTradeNo()); // 商户订单编号
        paramMap.put("out_refund_no","tk" + paymentInfo.getOutTradeNo()); // 商户退款单号
        // paramMap.put("total_fee",paymentInfoQuery.getTotalAmount().multiply(new BigDecimal("100")).longValue()+"");
        // paramMap.put("refund_fee",paymentInfoQuery.getTotalAmount().multiply(new BigDecimal("100")).longValue()+"");
        paramMap.put("total_fee","1");
        paramMap.put("refund_fee","1");
        //3.对接微信接口
        HttpClient client = new HttpClient("https://api.mch.weixin.qq.com/secapi/pay/refund");
        client.setHttps(true);
        client.setCert(true);
        client.setCertPassword(ConstantPropertiesUtils.PARTNER);
        client.setXmlParam(WXPayUtil.generateSignedXml(paramMap,ConstantPropertiesUtils.PARTNERKEY));
        client.post();
        //4.处理返回数据
        String xmlContent = client.getContent();
        //4.1转成map
        Map<String, String> resultMap = WXPayUtil.xmlToMap(xmlContent);
        //4.2判断是否退款成功
        if (resultMap.get("return_code").equals("SUCCESS") &&
                resultMap.get("result_code").equals("SUCCESS")){
            //成功 更新退款状态
            refundInfo.setTradeNo(resultMap.get("refund_id")); // 微信退款的交易流水号
            refundInfo.setRefundStatus(RefundStatusEnum.REFUND.getStatus());
            refundInfo.setCallbackTime(new Date());
            refundInfo.setCallbackContent(JSONObject.toJSONString(resultMap));
            refundInfo.setUpdateTime(new Date());
            refundInfoService.updateById(refundInfo);
            return true;
        }
        return false;
    }
}
